import time
from threading import Thread

import wx
import app.UI

from app import utils, UI

logMgr = utils.logMgr





class ReadWriteWindow(wx.BoxSizer):
    def __init__(self, ctx):
        super().__init__(orient=wx.HORIZONTAL)
        self.ctx = ctx
        self.readIntervalEnable = False
        self.readIntervalMills = 0
        leftBox = self.initLeft(ctx)
        rightBox = self.initRight(ctx)

        self.Add(leftBox, 1, flag=wx.EXPAND)
        self.Add(UI.Divider(ctx, (1, 1)), 0, flag=wx.EXPAND)
        self.Add(rightBox, 3, flag=wx.EXPAND)

    def initLeft(self, ctx):
        leftBox = wx.BoxSizer(wx.VERTICAL)

        addrBox = wx.BoxSizer(wx.HORIZONTAL)
        self.et_addr = wx.TextCtrl(ctx, -1, "", size=(70, 20))
        addrBox.Add(wx.StaticText(ctx, -1, label="寄存器(HEX):", size=(80, 20)), 0, flag=wx.LEFT, border=20)
        addrBox.Add(self.et_addr, 0, flag=wx.LEFT, border=0)
        leftBox.Add(addrBox, 0, flag=wx.TOP, border=10)

        readSizeBox = wx.BoxSizer(wx.HORIZONTAL)
        self.et_read_size = wx.TextCtrl(ctx, -1, "", size=(70, 20))
        readSizeBox.Add(wx.StaticText(ctx, -1, label="读取长度:", size=(80, 20)), 0, flag=wx.LEFT, border=20)
        readSizeBox.Add(self.et_read_size, 0, flag=wx.LEFT, border=0)
        leftBox.Add(readSizeBox, 0, flag=wx.TOP, border=50)

        self.readBtn = wx.Button(ctx, -1, "读数据", pos=(120, 0), size=(120, 60))
        self.readBtn.Bind(wx.EVT_BUTTON, self.onReadClick)
        leftBox.Add(self.readBtn, 0, flag=wx.LEFT | wx.TOP, border=50)
        leftBox.Add(UI.Divider(ctx, (200, 1)), 0, wx.EXPAND | wx.TOP, 50)

        writeSizeBox = wx.BoxSizer(wx.HORIZONTAL)
        leftBox.Add(writeSizeBox, 0, flag=wx.TOP, border=10)
        self.writeBtn = wx.Button(ctx, -1, "写数据", pos=(120, 0), size=(120, 60))
        self.writeBtn.Bind(wx.EVT_BUTTON, self.onWriteClick)
        leftBox.Add(self.writeBtn, 0, flag=wx.LEFT | wx.TOP, border=50)
        return leftBox

    def initRight(self, ctx):
        rightBox = wx.BoxSizer(wx.VERTICAL)
        self.et_receive = wx.TextCtrl(ctx, -1, value="", size=(280, 230), style=wx.TE_MULTILINE)
        self.et_receive.SetEditable(False)
        self.et_receive.SetBackgroundColour((233, 233, 233))
        rightBox.Add(self.et_receive, 0, flag=wx.EXPAND, border=20)

        settingBox = wx.BoxSizer(wx.HORIZONTAL)
        self.cb_interval_read = wx.CheckBox(ctx, -1, "定时读取")
        self.cb_interval_read.Bind(wx.EVT_CHECKBOX, self.onBoxChangeListener)
        self.et_interval_read = wx.TextCtrl(ctx, -1, value=str(1000), size=(70, 20))
        self.et_interval_read.Bind(wx.EVT_TEXT, self.onIntervalMillChangeListener)
        settingBox.Add(self.cb_interval_read, 0, flag=wx.LEFT, border=20)
        settingBox.Add(self.et_interval_read, 0, border=0)
        settingBox.Add(wx.StaticText(ctx, -1, "ms", size=(40, 20)))

        self.btn_clear_window = wx.Button(ctx, -1, "清除窗口", size=(120, 25))
        self.btn_clear_window.Bind(wx.EVT_BUTTON, self.clearReceiveWindow)
        settingBox.Add(self.btn_clear_window, 0, flag=wx.EXPAND | wx.LEFT, border=315)
        rightBox.Add(settingBox, 0, flag=wx.EXPAND | wx.TOP | wx.BOTTOM, border=10)

        self.et_send = wx.TextCtrl(ctx, -1, "", size=(280, 150))
        self.et_send.SetBackgroundColour((255, 255, 255))
        rightBox.Add(self.et_send, 0, flag=wx.EXPAND, border=10)
        return rightBox

    def onReadClick(self, e):
        self.read()
        # count=self.GetItemCount()
        # print(count)
        # for i in range(0,count):
        #     self.Hide(i)
        # print(self.GetItemCount())

    def read(self):
        if self.et_addr.GetValue() == "" or self.et_read_size.GetValue() == "":
            return
        addr = int(self.et_addr.GetValue(), 16)
        cnt = int(self.et_read_size.GetValue(), 10)
        # print("read:"+addr+",cnt:"+cnt)
        recvBytes = self.ctx.master.read(addr, cnt)
        if type(recvBytes) == int:
            self.appendReceiveData(dataArr=[recvBytes])
        else:
            self.appendReceiveData(dataArr=recvBytes)

    def onWriteClick(self, e):
        addr = self.et_addr.GetValue()
        content = self.et_send.GetValue()
        if addr == "" or content == "":
            return
        arr=content.split(' ')
        bytes=[]
        for x in arr:
            bytes.append(int(x, 16))
        resBytes = self.ctx.master.writeArr(int(addr, 16),dat=bytes)
        self.appendReceiveData(dataArr=resBytes)
        logMgr.print("reg addr:" + addr + ",content:" + content)

    def clearReceiveWindow(self, e):
        self.et_receive.SetValue("")

    def appendReceiveData(self, dataArr):
        # logMgr.print("resp:"+utils.bytes2Hex(dataArr))
        self.et_receive.AppendText(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) +"-->"+utils.bytes2Hex(dataArr) + "\n")

    def onBoxChangeListener(self, e):
        cb = e.GetEventObject()
        if cb.GetValue():
            self.readIntervalMills = 0
            enable = True
            try:
                self.readIntervalMills = int(self.et_interval_read.GetValue(), 10)
            except ValueError:
                enable = False
            if enable and self.readIntervalMills > 0:
                self.enableIntervalRead()
            else:
                cb.SetValue(False)
        else:
            self.disableIntervalRead()

    def onIntervalMillChangeListener(self, e):
        self.disableIntervalRead()
        self.cb_interval_read.SetValue(False)

    def enableIntervalRead(self):
        self.readIntervalEnable = True
        th = Thread(target=self.readLoop, args=())
        th.start()

    def readLoop(self):
        while self.readIntervalEnable:
            self.read()
            time.sleep(self.readIntervalMills * 1.0 / 1000)

    def disableIntervalRead(self):
        self.readIntervalEnable = False
